package com.lcg.word.screen

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope
import com.lcg.base.net.Http
import com.lcg.base.showToast
import com.lcg.word.AudioViewModel
import com.lcg.word.Base
import com.lcg.word.DigitalInkManager
import com.lcg.word.bean.BookUnit
import com.lcg.word.bean.Word
import com.lcg.word.bean.wordDao
import com.lcg.word.ui.WritingBoard
import com.lcg.word.viewModel
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * 拼写
 *
 * @author lei.chuguang Email:475825657@qq.com
 */
@Preview
@Composable
@Destination
fun SpellScreen(
    navigator: DestinationsNavigator? = null,
    unit: BookUnit = BookUnit(),
    vm: SpellVM = viewModel(navigator, unit.name ?: "")
) {
    LaunchedEffect(Unit) {
        vm.load(unit)
    }
    Base(vm) {
        Box(modifier = Modifier.fillMaxSize()) {
            WritingBoard(vm.resetFlag)
            LinearProgressIndicator(
                progress = vm.progress.toFloat() / vm.total,
                Modifier
                    .fillMaxWidth()
                    .height(1.dp)
                    .align(Alignment.TopCenter)
            )
            Icon(
                imageVector = Icons.Default.Delete,
                contentDescription = vm.word?.cn ?: "",
                modifier = Modifier
                    .size(48.dp)
                    .align(Alignment.TopEnd)
                    .clickable(onClick = { vm.reset() })
                    .padding(10.dp),
                tint = Color.Black
            )
            Row(
                Modifier.clickable(onClick = { vm.play() })
            ) {
                Icon(
                    imageVector = if (vm.play) Icons.Default.Notifications else Icons.Default.PlayArrow,
                    contentDescription = "播放",
                    modifier = Modifier
                        .size(48.dp)
                        .padding(10.dp),
                    tint = Color.Black
                )
                Text(text = vm.word?.getCN() ?: "", Modifier.align(Alignment.CenterVertically))
            }
            Button(
                onClick = { vm.next() },
                modifier = Modifier
                    .align(Alignment.BottomEnd)
                    .offset((-10).dp, (-10).dp)
            ) {
                Text(text = "下一个")
            }
            //单词
            Text(
                text = vm.recognizeText,
                color = if (vm.status == 1) Color.Green else Color.Black,
                modifier = Modifier
                    .align(Alignment.TopCenter)
                    .offset(y = 10.dp)
            )
            if (vm.status == 0)
                Text(
                    text = vm.word?.en ?: "",
                    modifier = Modifier
                        .fillMaxSize()
                        .background(Color(0x39000000))
                        .clickable { },
                    fontSize = 50.sp,
                    color = Color.Red,
                    textAlign = TextAlign.Center
                )
        }
    }
}

class SpellVM : AudioViewModel(), AudioViewModel.Audio {
    var recognizeText by mutableStateOf("")
    var resetFlag by mutableIntStateOf(0)
    override val url: String
        get() = word?.getUrl() ?: ""
    override var play: Boolean by mutableStateOf(false)

    //
    var word by mutableStateOf<Word?>(null)
    private var words = arrayListOf<Word>()
    private val indexes = arrayListOf<Int>()
    var progress by mutableIntStateOf(0)
    var total by mutableIntStateOf(1)

    /**单词状态，-1=不可见 0=错误 1=正确 */
    var status by mutableIntStateOf(-1)

    init {
        reset()
        DigitalInkManager.setInputListener {
            recognizeText = it
        }
    }

    fun load(unit: BookUnit) {
        if (words.isNotEmpty()) return
        //
        val id = unit.id
        val bookId = unit.book?.id
        val list = when {
            id != null && bookId != null -> {//本书复习：复习该书之前单元的单词
                wordDao.queryBuilder().where().eq("book_id", bookId).and().lt("unit_id", 1L).query()
            }

            id == null && bookId != null -> {//复习该书之前的单词
                wordDao.queryBuilder().where().lt("book_id", bookId).query()
            }

            id != null && bookId == null -> {//学习该单元的词
                wordDao.queryForEq("unit_id", unit.id)
            }

            else -> {//复习已学过的单词
                wordDao.queryBuilder().where().gt("writing", 1L).query()
            }
        }
        //
        // 选词:
        //1.按最近做题时间排序
        list.sortBy { it.lastTimeWriting }
        //2.选出=0...01的
        filterWith(list) { it.writing == 1L }
        //3.选出=0...010的
        filterWith(list) { it.writing == 2L }
        //4.选出***0的
        filterWith(list) { it.writing and 1L == 0L }
        //5.选出***01的，注意这里1L不包含在里面了，并且做题超过两次了
        filterWith(list) { it.writing and 1L == 0L }
        //最后.按错误率排序，
        // xxx 这部分先不做：同一错误率做题次数的排前面,同一做题次数，再按时间排序
        if (list.isNotEmpty()) {
            list.sortBy { it.writingRight.toFloat() / it.writingCount }
            for (word1 in list) {
                if (words.size >= limit) break
                words.add(word1)
            }
        }
        //
        total = words.size
        repeat(total) {
            indexes.add(it)
        }
        setNewWord()
    }

    private val limit = 30

    /**筛选*/
    private fun filterWith(list: MutableList<Word>, filter: (Word) -> Boolean) {
        if (list.isEmpty()) return
        var index = 0
        while (index < list.size) {
            if (words.size >= limit) break
            //
            val word1 = list[index++]
            if (filter(word1)) {
                list.removeAt(--index)
                words.add(word1)
            }
        }
    }

    /**设置新单词*/
    private fun setNewWord() {
        status = -1
        //
        if (indexes.isEmpty()) {
            complete()
        } else {
            word = words[indexes.random()]
            //
            if (word!!.writing == 0L) word!!.writing = 1L
            word!!.writing = word!!.writing shl 1
            wordDao.update(word)
            //
            DigitalInkManager.setCompareWord(word!!.en) {
                recognizeOk()
            }
        }
    }

    /**完成*/
    private fun complete() {
        showToast("恭喜通关！")
        viewModelScope.launch {
            delay(300)
            back()
        }
    }

    /**识别成功*/
    private fun recognizeOk() {
        status = 1
        indexes.remove(words.indexOf(word))
        progress++
        //
        word!!.writing = word!!.writing and 1
        word!!.lastTimeWriting = Http.date.time
        wordDao.update(word)
        //
        viewModelScope.launch {
            delay(300)
            reset()
            setNewWord()
        }
    }

    fun play() {
        play(this)
    }

    fun reset() {
        recognizeText = ""
        resetFlag++
        DigitalInkManager.reset()
    }

    fun next() {
        status = 0
        viewModelScope.launch {
            delay(3000)
            reset()
            setNewWord()
        }
    }

    override fun onCleared() {
        DigitalInkManager.setInputListener(null)
        DigitalInkManager.setCompareWord(null, null)
    }
}